package stopwatch;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.lang.reflect.InvocationTargetException;

import junit.extensions.PrivilegedAccessor;

import org.junit.Test;

import database.Database;

import tests.DatabaseTest;
import utility.Constants;

public class StopwatchTest {
	
	private final int TRIALS = 5;
	
	@Test
	public void testSave() throws SecurityException, NoSuchFieldException, NoSuchMethodException, InterruptedException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
		Database.init();
		
		Stopwatch test = new Stopwatch(new StopwatchPanel());
		
		
		final String activities[] = {"DSA", "PP", "Algebra", "Deutsch", "Italian", "OS","Sleep", "All", "Maintenance"};
		Database.addActivity(activities);
		
		Constants.updateActivitiesList();
		int n = Constants.activities.length;
		
		boolean lap; 
		final long SLEEP = 2000;
		for (int i= 0; i<TRIALS; i++){
			final int activityId = (i%n)+1;
			lap = (i % 10 == 0)? true:false;
			
			test.startOrPauseOrResume(activityId, lap); /* start */
					
			for (int j=0; j<n; j++){
				Thread.sleep(SLEEP);
				test.startOrPauseOrResume(activityId, lap); // start
				assertTrue(!test.isSessionPaused() && (Boolean) PrivilegedAccessor.getValue(test, "sessionIsRunning"));
					Thread.sleep(SLEEP);

				test.startOrPauseOrResume(activityId, lap); // pause
				assertTrue(test.isSessionPaused() && (Boolean) PrivilegedAccessor.getValue(test, "sessionIsRunning"));
				Thread.sleep(SLEEP);

				test.startOrPauseOrResume(activityId, lap); // start
				assertTrue(!test.isSessionPaused() && (Boolean) PrivilegedAccessor.getValue(test, "sessionIsRunning"));
				Thread.sleep(SLEEP);
			}
		}
		try {
			PrivilegedAccessor.invokeMethod(DatabaseTest.class, "dropTables()");
		} catch (Exception e) {
			fail();
			e.printStackTrace();
		}
	}
	

	@Test
	public void testStartOrPauseOrResume() throws SecurityException, NoSuchFieldException, NoSuchMethodException, InterruptedException {
		Database.init();	
		final long SLEEP = 2000;
		final String activities[] = {"DSA", "PP", "Algebra", "Deutsch", "Italian", "OS","Sleep", "All", "Maintenance"};
		Database.addActivity(activities);
		Constants.updateActivitiesList();
		
		int n = Constants.activities.length;
		final stopwatch.Stopwatch test = new stopwatch.Stopwatch(new StopwatchPanel());
		Thread.sleep(SLEEP);
		boolean lap; 
		for (int i= 0; i<TRIALS; i++){
			final int activityId = (i%n)+1;
			lap = (i % 10 == 0)? true:false;
			test.startOrPauseOrResume(activityId, lap); // start 
			assertTrue(!test.isSessionPaused() && (Boolean) PrivilegedAccessor.getValue(test, "sessionIsRunning"));
			Thread.sleep(SLEEP);
			for (int j=0; j<n; j++){
				Thread.sleep(SLEEP);
				test.startOrPauseOrResume(activityId, lap); // pause
				assertTrue(test.isSessionPaused() && (Boolean) PrivilegedAccessor.getValue(test, "sessionIsRunning") );
				
				Thread.sleep(SLEEP);
				
				test.startOrPauseOrResume(activityId, lap); // resume
				assertTrue(!test.isSessionPaused() && (Boolean) PrivilegedAccessor.getValue(test, "sessionIsRunning"));
			}
			Thread.sleep(SLEEP);
			test.startOrPauseOrResume(activityId, lap); // pause
			assertTrue(test.isSessionPaused() && (Boolean) PrivilegedAccessor.getValue(test, "sessionIsRunning"));
		}
		
		try {
			PrivilegedAccessor.invokeMethod(DatabaseTest.class, "dropTables()");
		} catch (Exception e) {
			
			e.printStackTrace();
			fail();
		}
	}
	
	
	/*
	@Test
	public void testStartPauseResume() throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InterruptedException{
		Stopwatch test = new Stopwatch(new StopwatchPanel());
		final long SLEEP = 2000;
		Thread.sleep(SLEEP);
		Database.init();
		final String activities[] = {"DSA", "PP", "Algebra", "Deutsch", "Italian", "OS","Sleep", "All", "Maintenance"};
		Database.addActivity(activities);
		Thread.sleep(SLEEP);
		Constants.updateActivitiesList();
		int n = Constants.activities.length;
				
		boolean lap;
		for (int i= 0; i<n; i++){
			Thread.sleep(SLEEP);
			final int activityId = (i%n)+1;
			PrivilegedAccessor.setValue(test, "activityId", activityId);
			
			lap = (i % 10 == 0)? true:false;
			PrivilegedAccessor.invokeMethod(test, "start(int)",lap);		
			assertTrue(!test.isSessionPaused() && (Boolean) PrivilegedAccessor.getValue(test, "sessionIsRunning"));
		//	assertEquals( PrivilegedAccessor.getValue(test, "counter.mm"), 0);
			Thread.sleep(SLEEP);

			test.save();
			assertTrue(!test.isSessionPaused() && !(Boolean) PrivilegedAccessor.getValue(test, "sessionIsRunning"));
		//	assertEquals( PrivilegedAccessor.getValue(test, "counter.mm"), 0);
			Thread.sleep(SLEEP);

			PrivilegedAccessor.invokeMethod(test, "start(int)",lap);			
			assertTrue(!test.isSessionPaused() && (Boolean) PrivilegedAccessor.getValue(test, "sessionIsRunning"));
		//	assertEquals( PrivilegedAccessor.getValue(test, "counter.mm"), 0);
			
						
			for (int j=0; j<TRIALS/10; j++){
				Thread.sleep(SLEEP);
			
				PrivilegedAccessor.invokeMethod(test, "pause()");
				assertTrue(test.isSessionPaused() && (Boolean) PrivilegedAccessor.getValue(test, "sessionIsRunning")); 
			//				&& (Integer) PrivilegedAccessor.getValue(test, "counter.mm") >= 0);
				Thread.sleep(SLEEP);

				PrivilegedAccessor.invokeMethod(test, "resume(int)",lap);
				assertTrue(!test.isSessionPaused() && (Boolean) PrivilegedAccessor.getValue(test, "sessionIsRunning"));
				
			}
			test.save();
		}
		try {
			PrivilegedAccessor.invokeMethod(DatabaseTest.class, "dropTables()");
		} catch (Exception e) {
			fail();
			e.printStackTrace();

		}
	}*/
}
